home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
pcroct89.arc
/
PCTOCT.ARC
/
PRTSCR1.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-03-21
|
6KB
|
238 lines
Comment |
First module in the replacement PrintScreen program. This module
contains the code which intercepts Shift-PrtScr from the keyboard,
determines the current video mode, printer address, and calls the
appropriate routine in Listing 2. It also contains the installation
code.
Save as PRTSCR1.ASM
Compile: MASM /Ml PRTSCR;
or
TASM /Ml PRTSCR
|
;Remove the comment mark from the next line if you are using TASM
;TASM equ 1
Ifdef TASM
QUIRKS
MASM51
Endif
.MODEL SMALL,C
extrn textmode:near, lo_res:near, med_res:near, hi_res:near
extrn cga_4:near, cga_6:near, ega_clr:near, ega_mono:near
.STACK 100h
.DATA
db 200h dup (?)
newstk equ $ ;Start of ISR stack
base_port dw ?
public vidmode, vidcols, vidrows, vidseg, vidoff, vidpage
vidmode dw ? ;Variables describing
vidcols dw ? ; current video state
vidrows dw ?
vidseg dw ?
vidoff dw ?
vidpage dw ?
; Call table for print-screen routines
vidroutine dw offset textmode, offset textmode ;Modes 0,1
dw offset textmode, offset textmode ;Modes 2,3
dw offset lo_res, offset lo_res ;Modes 4,5
dw offset med_res, offset textmode ;Modes 6,7
dw 5 dup (offset none) ;Modes 8-0C
dw offset lo_res, offset med_res ;Modes 0D,0E
dw offset hi_res, offset hi_res ;Modes 0F,10
Ifndef TASM
public _acrtused
_acrtused dw ? ;Keep MSC/QC from loading startup
;code.
Endif
signon db 13,10,"PC Resource's PrintScreen Program is installed."
db 13,10,"You can now print graphics and text."
db 13,10,"$"
.CODE
;----------
; CS-based data locations
;----------
old_sp dw ?
old_ss dw ?
start_flag db 0
;------------
; This becomes the new Int 05h
; and intercepts Shift-Prtscr keypresses.
; It must change to our local stack, save
; registers, and restore everything when
; we're done.
;------------
new_int5 proc
test cs:start_flag,-1 ;Already here?
jnz int5_exit ;Yes -- just leave
mov cs:start_flag,1 ;Show we've started
push ax ;Save AX register for return
cli ;No interrupts
mov cs:[old_ss],ss ;Save the stack
mov cs:[old_sp],sp
mov ax,@data ;Move to our stack
mov ss,ax
mov sp,offset newstk
sti ;Allow interrupts
push bx ;Save all registers
push cx
push dx
push bp
push di
push si
push ds
push es
mov ax,@data ;Set DS to our data
mov ds,ax
call setup ;And start to work
pop es ;Recover registers
pop ds
pop si
pop di
pop bp
pop dx
pop cx
pop bx
cli ;No interrupts during
mov ss,cs:[old_ss] ; stack switch
mov sp,cs:[old_sp]
sti ;Allow interrupts
pop ax ;Get original AX
mov start_flag,0 ;Show that we're leaving
int5_exit:
iret ;We're done
new_int5 endp
;------------
; Read video and printer info from BIOS RAM,
; then call the correct PrtScr routine.
;------------
setup proc
mov ax,40h ;ES ==> ROM BIOS data
mov es,ax
mov dx,es:[8] ;Get printer port addr.
mov base_port,dx ;Save it
or dx,dx ;Is a printer attached?
jz exit ;No -- forget it
inc dx ;DX ==> status port
in al,dx ;Read status
and al,1000B ;Test bit 3
jz exit ;Error -- skip everything
mov al,es:[49h] ;Get video mode
cbw ;Change byte to word
mov vidmode,ax ;Save mode
cmp ax,10h ;Is it okay?
ja exit ;VGA/MCGA special: exit
mov ax,es:[4ah] ;Get display columns
mov vidcols,ax ; and save
mov al,es:[84h] ;Get display rows
or al,al ;Is it 0?
jnz @F ;No -- go
mov al,24 ;Else assume default
@@: cbw ;Make into word
mov vidrows,ax ; and save it
cmp vidmode,7 ;Monochrome mode?
jne @F ;No -- go
mov vidseg,0b000h ;Yes -- video base at B000
jmp short setup_1 ;Skip other tests
@@: jg @F ;Go if EGA graphics
mov vidseg,0b800h ;Video base for CGA & color text
jmp short setup_1
@@: mov vidseg,0a000h ;Video base for EGA/VGA graphics
setup_1:
mov ax,es:[4eh] ;Video offset address
mov vidoff,ax ; and save it
mov bx,vidmode ;Get mode back
add bx,bx ;* 2 for table offset
add bx,offset vidroutine ;Add table address
call [bx] ;Call routine
exit: ret ;We're done
setup endp
;------------
; Dummy routine if a PCjr/Tandy 1000
; or illegal video mode appears to be
; active
;------------
none proc
ret
none endp
;------------
; Send a byte to the printer
; If the printer signals an error,
; simply return with the byte unsent.
; If the printer is busy, wait for it.
;------------
prt_out proc near uses dx, char:word
mov dx,base_port
inc dx ;DX ==> status port
@@: in al,dx ;Get status
test al,1000b ;Error?
jz exit ;Yes -- forget it
test al,80h ;Busy?
jz @B ;Yes -- wait til ready
mov ax,char ;Get char to print
dec dx ;DX ==> data port
out dx,al ;Send character
inc dx
inc dx ;DX ==> output control port
mov al,1101b ;Bit 0 is strobe bit
out dx,al ;Turn strobe on
dec al ;(now it's 1100b)
out dx,al ;Turn strobe off
exit: ret
prt_out endp
;------------
; Send a value to a specific port
; on the EGA Graphics Controller chip
;------------
gc_out proc near index:word, value:word
mov dx,3ceh ;Graphics controller port
mov ax,index ;Index in AL
mov bx,value ;Value in BL
mov ah,bl ;Value in AH
out dx,ax ;Send it out
ret
gc_out endp
;------------
; Install the Print-Screen program in
; memory and exit. Note that this does
; not check to see if it is already installed.
; (You may want to add that).
;------------
install proc near
mov ax,@code ;Get code segment
mov ds,ax ; into DS
mov dx,offset new_int5 ;Get new Int 5 address
mov ax,2505h ;Set as new Int 5
int 21h
mov ax,@data ;Now get data segment
mov ds,ax ; into DS
mov dx,offset signon ;DS:DX ==> sign-on message
mov ah,9 ;Print a string
int 21h ;Tell the world
mov dx,0abh ;Paragraphs to keep (from MAP file)
mov ax,3100h ;Terminate & stay resident
int 21h
install endp
end install